package com.zzh.jn_erp.common.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Configuration
public class ApplicationContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    private static DefaultListableBeanFactory defaultListableBeanFactory;

    public ApplicationContextUtil() {
        System.out.println(11);
        System.out.println(applicationContext);
    }

    public static void FieldsInto(Class<?> clazz, Object object) {
        Field[] fileds = clazz.getDeclaredFields();
        Field[] var3 = fileds;
        int var4 = fileds.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Field f = var3[var5];
            f.setAccessible(true);

            try {
                if (getBean(f.getName()) != null) {
                    f.set(object, getBean(f.getName()));
                }
            } catch (Exception var8) {
                var8.printStackTrace();
            }
        }

    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.defaultListableBeanFactory = (DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory();
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static final Object getBean(String beanName) {
        return applicationContext != null && applicationContext.containsBean(beanName) ? applicationContext.getBean(beanName) : null;
    }

    public static final <T> T getBean(Class<T> requiredType) {
        return applicationContext.getBean(requiredType);
    }

    public static final <T> T getBean(String beanName, Class<T> requiredType) {
        return applicationContext != null && applicationContext.containsBean(beanName) ? applicationContext.getBean(beanName, requiredType) : null;
    }

    public static BeanDefinition createBean(String className, String beanKey, Map<String, Object> propertyMap, Map<String, String> referenceMap, List<Object> propertyConstrList, List<String> referenceConstrList, String destroyMethod) {
        if (defaultListableBeanFactory.containsBeanDefinition(beanKey)) {
            return defaultListableBeanFactory.getBeanDefinition(beanKey);
        } else {
            BeanDefinitionBuilder beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(className);
            beanDefinition.getBeanDefinition().setAttribute("id", beanKey);
            Iterator referenceKeys;
            String keyString;
            if (propertyMap != null && !propertyMap.isEmpty()) {
                referenceKeys = propertyMap.keySet().iterator();

                while(referenceKeys.hasNext()) {
                    keyString = (String)referenceKeys.next();
                    beanDefinition.addPropertyValue(keyString, propertyMap.get(keyString));
                }
            }

            if (referenceMap != null && !referenceMap.isEmpty()) {
                referenceKeys = referenceMap.keySet().iterator();

                while(referenceKeys.hasNext()) {
                    keyString = (String)referenceKeys.next();
                    beanDefinition.addPropertyReference(keyString, (String)referenceMap.get(keyString));
                }
            }

            int i;
            if (propertyConstrList != null && !propertyConstrList.isEmpty()) {
                for(i = 0; i < propertyConstrList.size(); ++i) {
                    beanDefinition.addConstructorArgValue(propertyConstrList.get(i));
                }
            }

            if (referenceConstrList != null && !referenceConstrList.isEmpty()) {
                for(i = 0; i < referenceConstrList.size(); ++i) {
                    beanDefinition.addConstructorArgReference((String)referenceConstrList.get(i));
                }
            }

            if (destroyMethod != null && !destroyMethod.isEmpty()) {
                beanDefinition.setDestroyMethodName(destroyMethod);
            }

            defaultListableBeanFactory.registerBeanDefinition(beanKey, beanDefinition.getBeanDefinition());
            return beanDefinition.getRawBeanDefinition();
        }
    }
}
